import 'dart:async';
import 'package:amap_location_fluttify/amap_location_fluttify.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:wk_weather/bean/EnventChangeBean.dart';
import 'package:wk_weather/bean/CityInfo.dart';
import 'package:wk_weather/myConfig/weather_type.dart';
import 'package:wk_weather/utils/DialogTool.dart';
import 'package:wk_weather/utils/LocationUtil.dart';
import 'package:wk_weather/utils/MyLogTool.dart';
import 'package:wk_weather/utils/SharedPreferenceTool.dart';
import 'package:wk_weather/utils/ToastUtils.dart';
import 'package:wk_weather/views/MyApp.dart';


part 'CityEvent.dart';

part 'CityState.dart';

/*
 Bloc 将  Event 事件转换为 States 状态.
 每个 Bloc 都有一个 add 方法，用来添加新的 Event 到 mapEventToState 中；
 */

class CityBloc extends Bloc<CityEvent, CityState> {

  CityBloc( ) : super( CityInit() );

  @override
  Stream<CityState> mapEventToState (  CityEvent event, ) async* {

    if (event is FetchCityDataEvent) {
      yield* mapFetchCityDataEventToState();
    }

    else if (event is RequestLocationEvent) {
      // todo  正在定位
      showAppDialog(loadingMsg: "正在定位");

      // 单次定位 ，开始定位
      Location location = await AmapLocation.instance.fetchLocation();
      weatherPrint("定位结束: $location");


      CityModel cityModel = convert(location);
      cityModel.displayedName = WeatherUtils.getCityName(cityModel);

      List<CityModel> cityModels = [];
      if (cityModel.latitude == 0.0 || cityModel.longitude == 0.0) {
        ToastUtils.toastMsg("定位失败", globalKey.currentContext, duration: 5);
        cityModel = _buildDefault();
      }else{
        ToastUtils.toastMsg("定位成功", globalKey.currentContext, duration: 5);
      }
      cityModels = await insertCityMode(cityModel);
      eventBus.fire(MainBgChangeEvent());
      Navigator.of(globalKey.currentContext).pop();
      yield CitySuccess(cityModels);
    }

    else if (event is InsertCityData) {
      List<CityModel> cacheModels = await SharedPreferenceTool.getCityModels();
      bool needInsert = true;
      if (cacheModels != null && cacheModels.isNotEmpty) {
        cacheModels.forEach( (element) {
          if (event.cityModel.cityFlag == element.cityFlag) {
            needInsert = false;
            return;
          }
        });
      }

      if (!needInsert) {
        weatherPrint("城市已存在，不需要插入");
        return;
      }

      List<CityModel> cityModels = [];
      if (event.cityModel.latitude != 0.0 && event.cityModel.longitude != 0.0) {
        cityModels = await insertCityMode(event.cityModel);
      }
      eventBus.fire(MainBgChangeEvent());
      yield CitySuccess(cityModels);
    }

    else if (event is DeleteCityData) {
      List<CityModel> cacheModels = await SharedPreferenceTool.getCityModels();
      CityModel needRemoveModel;
      cacheModels.forEach((element) {
        if (element.cityFlag == event.cityFlag) {
          needRemoveModel = element;
        }
      });

      if (needRemoveModel != null) {
        cacheModels.remove(needRemoveModel);
        await SharedPreferenceTool.saveCityModels(cacheModels); // 重新保存 城市数据

        Map<String, String> allData = await SharedPreferenceTool.getAllWeatherModels();
        String key = LocationUtil.convertCityFlag(needRemoveModel.cityFlag, needRemoveModel.isLocated);
        if (allData != null && allData.containsKey(key)) {
          allData.remove(key);
          await SharedPreferenceTool.saveAllWeatherModels(allData); //  重新保存 天气数据
        }

        eventBus.fire(MainBgChangeEvent());
        yield CitySuccess(cacheModels);
      }
    }
  }

  CityModel _buildDefault() {
    CityModel cityModel = CityModel(
      latitude: 39.904989,
      longitude: 116.405285,
      country: "中国",
      province: "北京市",
      district: "东城区",
      displayedName: "北京市",
      isLocated: true,
    );
    return cityModel;
  }

  Future<List<CityModel>> insertCityMode(CityModel cityModel) async {
    weatherPrint("开始插入城市数据 $cityModel");
    List<CityModel> cityModels = await SharedPreferenceTool.getCityModels();
    if (cityModels == null) {
      cityModels = [];
    }
    if (cityModels.isNotEmpty) {
      CityModel needRemoveModel;
      cityModels.forEach((element) {
        if (cityModel.isLocated == true) {
          needRemoveModel = element;
          return;
        }
      });
      if (needRemoveModel != null) {
        weatherPrint("定位城市需要先从 CityModels 中移除");
        cityModels.remove(needRemoveModel);
      }
    }
    if (cityModel.isLocated == true) {
      cityModels.insert(0, cityModel);
    } else {
      cityModels.add(cityModel);
    }
    await SharedPreferenceTool.saveCityModels(cityModels);
    weatherPrint("插入成功后 size: ${cityModels?.length}");
    return cityModels;
  }

  CityModel convert(Location location) {
    return CityModel(
        latitude: location.latLng.latitude,
        longitude: location.latLng.longitude,
        country: location.country,
        province: location.province,
        city: location.city,
        district: location.district,
        poiName: location.poiName,
        street: location.street,
        streetNumber: location.streetNumber,
        isLocated: true);
  }

  Stream<CityState> mapFetchCityDataEventToState() async* {
    var cityModels = await SharedPreferenceTool.getCityModels();
    if (cityModels == null || cityModels.isEmpty) {
      weatherPrint('本地没有城市数据 ');
      yield CityInit();
    } else {
      weatherPrint('成功获取到城市列表数据 size: ${cityModels.length}');
      yield CitySuccess(cityModels);
    }
  }


}
